import sys

sys.path.append("../../")
import app
from db import db_utils
from model.entity.original_covid19_map_wangyi import OriginalCovid19MapWangyi


#    这个是insert方法呀~ 它接收一个数据表的实体类(实体类也是代码生成的哦) 并将实体类的数据插入到数据库中 - 主键给None的话数据库会自增哦
#    值得注意的是实体类中只有 <不为None>的数据才会被插入数据库中 也就是说 至少得保证数据表中非空的字段有数据
#    如果插入成功时 insert方法会返回插入的id哦
#    例子: xxx = xxxxxx() xxx.xx = <要设置的值> insert(xxx)即可   - xxxxxx()表示实例化实体类
def insert(table_entity):
    if not type(table_entity).__name__ == 'OriginalCovid19MapWangyi':
        app.App().log.error("insert方法需要传递表[original_covid19_map_wangyi]的实体类哦~")
        return
    column_list = table_entity.get_column_list()
    columns_sql = ""
    column_spaces = ""
    columns_value = []
    for column in column_list:
        value = getattr(table_entity,column)
        if value is not None and column != 'id':
            columns_sql = columns_sql + column + ","
            columns_value.append(value)
            if type(value).__name__ == 'int':
                column_spaces = column_spaces + "%d,"
            else:
                column_spaces = column_spaces + "'%s',"
    columns_sql = columns_sql[:-1]
    column_spaces = column_spaces[:-1]

    conn = db_utils.get_conn()
    cur = conn.cursor()
    str = """
            insert into original_covid19_map_wangyi("""+columns_sql+""") values("""+column_spaces+""")
    """
    sql = str % tuple(columns_value)
    app.App().log.info("执行sql：\n"+sql)
    cur.execute(sql)
    insert_id = cur.lastrowid

    conn.commit()
    cur.close()
    conn.close()
    return insert_id


#    这个是批量insert方法呀~ 它接收一个<list> -list中的每一项都得是数据表的实体类哦 - 主键给None的话数据库会自增哦
#    值得注意的是实体类中只有 批量插入方法必须得指定<实体类中的所有值> -这里偷了点懒~
#    例子:  xxx = []  xx = xxxxx() xx.xx = <值> xxx.append(xx) insert_all(xxx)  - xxxxxx()表示实例化实体类
def insert_all(table_entitys):
    if not isinstance(table_entitys,list):
        app.App().log.error("insert_all方法需要传递一个list哦~")
        return
    res_entitys = []
    for entitys in table_entitys:
        # 格式化数据 None值转为空字符串
        column_list = entitys.get_column_list()
        for column in column_list:
            if getattr(entitys, column) is None:
                setattr(entitys, column, "")
        field_tuple = (entitys.address_name,entitys.address_name_en,entitys.parent_address_id,entitys.total_confirm,entitys.total_dead,entitys.total_heal,entitys.today_confirm,entitys.today_dead,entitys.today_heal)
        res_entitys.append(field_tuple)
    conn = db_utils.get_conn()
    cur = conn.cursor()

    sql = """
            insert into original_covid19_map_wangyi(address_name,address_name_en,parent_address_id,total_confirm,total_dead,total_heal,today_confirm,today_dead,today_heal) values(%s,%s,%s,%s,%s,%s,%s,%s,%s)
    """
    app.App().log.info("[批量插入] 执行sql：\n" + sql)
    app.App().log.info("[批量插入] 插入数据: \n")
    print(res_entitys)
    cur.executemany(sql, res_entitys)

    conn.commit()
    cur.close()
    conn.close()


#    这个是update方法呀~ 它接收一个数据表的实体类(实体类也是代码生成的哦) 并修改数据库中的相应字段<实体类中不为None的字段>
#    值得注意的是<主键不能为None>
#    例子:  xxx = xxxxxx() xxx.xx = <要设置的值> update(xxx)即可  - xxxxxx()表示实例化实体类
def update(table_entity):
    if not type(table_entity).__name__ == 'OriginalCovid19MapWangyi':
        app.App().log.error("update方法需要传递表[original_covid19_map_wangyi]的实体类哦~")
        return
    table_id = table_entity.id
    if table_id is None:
        app.App().log.error("update方法主键不能为[None]哦~")
        return
    column_list = table_entity.get_column_list()
    set_sql = ""
    change_value_columns = []
    for column in column_list:
        value = getattr(table_entity,column)
        if value is not None and column != 'id':
            set_sql = set_sql + column + "=" + "%s" + ","
            change_value_columns.append(value)
    change_value_columns.append(table_id)
    set_sql = set_sql[:-1]
    conn = db_utils.get_conn()
    cur = conn.cursor()

    str = """
            update original_covid19_map_wangyi set """+ set_sql +""" where id=%d
    """
    sql = str % tuple(change_value_columns)
    app.App().log.info("执行sql：\n" + sql)
    cur.execute(sql)

    conn.commit()
    cur.close()
    conn.close()


#    这个是delete方法呀~ 它接收一个数据表的实体类(实体类也是代码生成的哦) 并删除数据库中的相应行 - 根据实体中的主键来判断删除哪一行
#    值得注意的是<主键不能为None>
#    例子:  xxx = xxxxxx() xxx.xx = <主键的值> delete(xxx)即可  - xxxxxx()表示实例化实体类
def delete(table_entity):
    if not type(table_entity).__name__ == 'OriginalCovid19MapWangyi':
        app.App().log.error("delete方法需要传递表[original_covid19_map_wangyi]的实体类哦~")
        return
    table_id = table_entity.id
    if table_id is None:
        app.App().log.error("delete方法主键不能为[None]哦~")
        return

    conn = db_utils.get_conn()
    cur = conn.cursor()

    sql = """
            DELETE FROM original_covid19_map_wangyi where id=%d
    """ % table_id
    app.App().log.info("执行sql：\n" + sql)
    cur.execute(sql)

    conn.commit()
    cur.close()
    conn.close()


# 这个方法更具实体类的主键 来判断该保存还是更新 - 主键为None则插入 否则更新
def insert_or_update(table_entity):
    if not type(table_entity).__name__ == 'OriginalCovid19MapWangyi':
        app.App().log.error("insert_or_update方法需要传递表[original_covid19_map_wangyi]的实体类哦~")
        return
    table_id = table_entity.id
    if table_id is None:
        insert(table_entity)
    else:
        update(table_entity)


# 获取该表的所有行 返回 list<数据表实体>
def get_all():
    conn = db_utils.get_conn()
    cur = conn.cursor()
    t_columns = OriginalCovid19MapWangyi().get_column_list()
    t_str = ""
    for name in t_columns:
        t_str = t_str + name + ","
    t_str = t_str[:-1]

    # 获取实体字段 使查询后的字段与实体字段顺序对应上
    sql = "select "+t_str+" from original_covid19_map_wangyi"
    app.App().log.info("执行sql：\n" + sql)
    cur.execute(sql)
    t = cur.fetchall()
    cur.close()
    conn.close()

    res = []
    for row in t:
        # 元组转实体
        en = OriginalCovid19MapWangyi()
        column_name_list = en.get_column_list()
        index = 0
        for column_name in column_name_list:
            # 通过反射为实体设置值 并同步位置
            setattr(en, column_name, row[index])
            index = index + 1
        res.append(en)
    return res


# 删除表中所有数据
def delete_all():
    conn = db_utils.get_conn()
    cur = conn.cursor()

    sql = "truncate table original_covid19_map_wangyi"
    app.App().log.info("执行sql：\n" + sql)
    cur.execute(sql)

    conn.commit()
    cur.close()
    conn.close()
